/*************************************************************************************************
 *	chatter_global.h *
 *	this file declear marcos and structures shared by client and server
 *
 *	e.g:
 *	FLAGfield	// [ 0000 0000 ~ 0111 1111 ] is considered as normal, send by client || server 
 *				// [ 1000 0000 ~ 1011 1111 ] is send by server, means success
 *				// [ 1100 0000 ~ 1111 1111 ] is send by server, means failure
 **************************************************************************************************
 * e.g: content in FLAGfield [0000 0000 ~ 0111 1111]
 *	
 *			[NAME]			[value]			[SEND BY]
 *
\**************************************************************/

#include <time.h>

#ifndef	_CHATTER_GLOBAL_H
#define _CHATTER_GLOBAL_H

#define		FLAG_SUCCESS				128		//:	S
#define		FLAG_FAILURE				192		//:	S
#define		FLAG_FAILURE_TOO_LARGE		193		//: S---packet is too large(larger than MAX_LEN_PCBODY)
#define		FLAG_FAILURE_UNKNOWN		194		//: S--- unknown flag
#define		FLAG_FAILURE_DB				195		//: S--- database error
#define		FLAG_FAILURE_ACC_NO			196		//:	S--- wrong account or passwd
#define		FLAG_FAILURE_BUDDY_NO		197		//: S--- do not have that buddy
#define		FLAG_FAILURE_BUDDY_OFF		198		//:	S--- that buddy is not online
#define		FLAG_FAILURE_REG			199		//: S--- that account has registered or NOT, use in two fields
#define		FLAG_FAILURE_PASSWD_NO		200		//: S--- that account's password is not correct

#define		FLAG_HELLO		0	//: S&C
#define		FLAG_LOGIN		1	//: C
#define		FLAG_STATUS_ON	2	//: S
#define		FLAG_STATUS_OFF	3	//: S
#define		FLAG_LOGOUT		4	//: C
 
#define		FLAG_MESSAGE	5	//: S&C
 
#define		FLAG_REQUEST_BUDDY_LIST		6	//:C
#define		FLAG_RESPONSE_BUDDY_LIST	7	//:S
 
#define		FLAG_SEARCH_NUM					13	//:C
#define		FLAG_SEARCH_NICK				14	//:C
#define		FLAG_RESPONSE_DETAIL			15	//:S
 
#define		FLAG_ADD_A_BUDDY		8	//:C& S if it sended by SERVER, then it's a notice
#define		FLAG_DEL_A_BUDDY		9	//:C

#define		FLAG_SET_DETAIL			10	//:C
 
#define		FLAG_REGISTER			11	//:C

#define		FLAG_SET_NICK			16	//:C
#define		FLAG_NICK_CHANGE		17	//:S


/***  the following 2 MIRCOS used in packet_header's length field ***/
#define		FLAG_MORE_FRAG			1	//:S ---- client never send packet larger than 1024
#define		FLAG_LAST_FRAG			0	//:C&S

/***********************	other marcos	********************************/

#define		MAX_LEN_ACCOUNT			(9+1)				//must NULL termialed
#define		MAX_LEN_PASSWD			(19+1)
#define		MAX_LEN_NICK			(19+1)
#define		MAX_LEN_CONTACT			(49+1)
#define		MAX_LEN_PCBODY			32767			//the max length of each packet's body
#define		MAX_LEN_MSG				768				//the max length of message(do not include any header)


/****************** TYPES *****************************/

/* header TYPE entire packets' */
/* the 'length' field identify a MAX LENGTH OF 32767,because it's first bit means:
 * 0 --- transmission finished,	
 * 1 --- more packet after this one, it's useful when send big packet such as buddylist infor */
typedef struct
{//SIZE 4 according to DEFAULT MEMORY ALIGNMENT <GCC 4.3>

	unsigned char	flag;				//flag field: 1 bytes
	short			length;				//content length (not include header)
										//NETWORK BYTE-ORDER
}packet_header_t;						

/* TYPE of HELLO packet */
typedef struct
{
	packet_header_t header;		//hello packet doesn't have content YET

}packet_hello_t;

/* TYPE of LOGIN packet */
typedef struct
{//SIZE 30
	char			from[MAX_LEN_ACCOUNT];	//account number
	char			md5sum[MAX_LEN_PASSWD];		//md5sum of (AccountPassword)
}packet_login_t;

/* TYPE of LOGOUT packet */
typedef struct
{//SIZE 10
	char			from[MAX_LEN_ACCOUNT];
}packet_logout_t;

/* TYPE of STATUS_ON packet */
typedef struct
{
	char			from[MAX_LEN_ACCOUNT];
}packet_status_on_t;

/* TYPE of STATUS_OFF packet */
typedef struct
{
	char			from[MAX_LEN_ACCOUNT];
}packet_status_off_t;

/* TYPE of SIMPLE_TM, which is used to descript time in a simple way */
typedef struct
{
	unsigned char	day;
	unsigned char	hour;
	unsigned char	minute;
	unsigned char	second;
}simple_tm_t;

/* TYPE of MESSAGE's HEADER packet */ 
/* because message's length is varible , so only define it's header here */
typedef struct
{//SIZE 24
	char			from[MAX_LEN_ACCOUNT];
	char			to[MAX_LEN_ACCOUNT];
	simple_tm_t		time;				//client should leave this field NULL

}packet_message_header_t;

/* TYPE of REQUEST_BUDDY_LIST */
typedef struct
{
	char			from[MAX_LEN_ACCOUNT];	
}packet_request_buddy_list_t;

/* TYPE of buddy,includes ACCOUNT & NICKNAME */
/* useful to  buddy_list  & SET_NICK & NICK_CHANGE*/
typedef struct
{
	char			account[MAX_LEN_ACCOUNT];
	char			nick[MAX_LEN_NICK];
	unsigned char	online;						// 0:offline, OR 1:online
}buddy_t;

/* TYPE of SET_NICK */
typedef struct
{
	char			from[MAX_LEN_ACCOUNT];
	char			nick[MAX_LEN_NICK];
}packet_set_nick_t;

/* TYPE of NICK_CHANGE */
typedef packet_set_nick_t packet_nick_change_t;

/* TYPE of RESPONSE_BUDDY_LIST's HEADER packet */
/* because buddy_list's length is varible, so only define it's header here */
typedef struct
{
	packet_header_t header;
}packet_reponse_buddy_list_header_t;

/* TYPE of ADD_A_BUDDY */
typedef struct
{
	char			from[MAX_LEN_ACCOUNT];
	char			account[MAX_LEN_ACCOUNT];
}packet_add_a_buddy_t;

/*TYPE of DEL_A_BUDDY */
typedef struct
{
	char			from[MAX_LEN_ACCOUNT];
	char			account[MAX_LEN_ACCOUNT];
}packet_del_a_buddy_t;

/* TYPE of account's DETAIL */
/* useful in SET_DETAIL AND SEARCH */
typedef struct
{//SIZE 152
	buddy_t		basic;
	char		registertime[22];		//format: YYYY-MM-DD HH:MM:SS
	char		birthday[12];			//format: YYYY-MM-DD
	char		contact[MAX_LEN_CONTACT];
	char		sex[6];
}account_detail_t;

/* TYPE of SET_DETAIL */
typedef struct
{//server ignore the ACCOUNT || REGISTERTIME'S change
	account_detail_t	detail;
}packet_set_detail_t;

/* TYPE of REGISTER */
typedef struct
{
	char				account[MAX_LEN_ACCOUNT];
	char				password[MAX_LEN_PASSWD];
}packet_register_t;

/* TYPE of SEARCH */
/* used to define SEARCH_(NUM||NICK) */
typedef struct
{
	char				from[MAX_LEN_ACCOUNT];
	char				content[MAX_LEN_NICK];
}packet_search_t;

typedef packet_search_t		packet_search_NUM;
typedef packet_search_t		packet_search_NICK;

/* TYPE of RESPONSE_DETAIL */
typedef packet_set_detail_t		packet_response_detail_t;

/* TYPE of ERR PACKET */
#define MAX_LEN_ERR		50
typedef struct
{
	char	err_str[MAX_LEN_ERR];
}packet_err_t;

/* TYPE of SUCC packet */
typedef packet_header_t		packet_succ_t;


#endif //_CHATTER_GLOBAL_H
